﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using RastinArgham.CRM.Business;
using RastinArgham.CRM.Services.DTOs;
using Mani.Common.Security;
using Mani.Common.WorkflowEngine;

namespace RastinArgham.CRM.Services
{
    public class CRMAPI : ICRMAPI
    {
        public int NewOrder(OrderDTO order)
        {
            SecurityManager securityManager = new SecurityManager();
            securityManager.authProvider = new WebAuthorizationProvider();
            aspnet_Users user = securityManager.GetUserInfo("crm_robot");
            CRMRepository crmRepository = new CRMRepository();

            try
            {
                Contact c = new Contact();

                DefaultAccountManager d = crmRepository.GetDefaultAccountManagerForCity(order.Contact.CityId.Value);
                if (d != null)
                    c.AccountManagerId = d.UserId;

                c.Address = order.Contact.Address;
                c.ContactTitle = order.Contact.ContactTitle;
                c.City = crmRepository.GetCityByid(order.Contact.CityId.Value);
                c.FullContactTitle = order.Contact.FullContactTitle;
                c.MobilePhone = order.Contact.MobilePhone;
                c.OperatorId = user.UserId;
                c.Phone = order.Contact.Phone;
                c.Email = order.Contact.Email;
                c.Website = order.Contact.Website;
                c.Fax = order.Contact.Fax;
                c.ZipCode = order.Contact.ZipCode;
                c.LeadSourceId = 1;
                c.Marketer = "وب سایت راستین ارقام";

                if (!String.IsNullOrEmpty(order.Contact.CampaignCode))
                {
                    Campaign camp = crmRepository.FindCampaignByCode(order.Contact.CampaignCode);
                    if (camp == null)
                    {
                        c.Campaign = crmRepository.AddCampaign(new Campaign { CampaignName = order.Contact.CampaignCode, CampaignCode = order.Contact.CampaignCode });
                    }
                    else
                    {
                        c.Campaign = camp;
                    }
                }

                if (order.Contact.ContactTypeId == 1)
                {
                    c.ContactType = crmRepository.GetContactTypeById((int)ContactTypes.Personal);
                    PersonalContact pc = NewPersonalContact(order);
                    pc.OperatorId = user.UserId;
                    crmRepository.AddPersonalContact(c, pc);
                }
                else if (order.Contact.ContactTypeId == 2)
                {
                    c.ContactType = crmRepository.GetContactTypeById((int)ContactTypes.Company);
                    CompanyContact cc = NewCompanyContact(order);
                    cc.OperatorId = user.UserId;
                    crmRepository.AddCompanyContact(c, cc);
                }

                Service s = crmRepository.GetServiceById(order.ServiceId);
                
                Order o = new Order();
                o.Service = s;
                o.ServiceId = s.ServiceId;
                o.ServiceStartDate = DateTime.Now;
                o.ServiceExpirationDate = o.ServiceStartDate.Value.AddMonths(s.ServicePeriod.Value);
                o.ServiceExpired = false;
                o.AccountManagerId = c.AccountManagerId;
                o.Contact = c;
                o.ContactId = c.ContactId;
                o.Price = s.Price;
                o.Quantity = 1;
                o.TaxPercent = s.TaxPercent;
                o.OrderDate = order.OrderDate;
                o.OperatorId = user.UserId;
                o.Activated = false;
                o.Registered = false;

                crmRepository.NewOrder(o);
                crmRepository.Save();

                WorkflowBasic wf = WorkflowFactory.Create(typeof(ServiceOrderWorkflow), o.OrderId, user.UserId);
                o.WorkflowInstanceId = wf.InstanceId;

                wf.SendEvent(WorkflowState.GetEventName(1, 5), user.UserId);

                RobotReport reportSuccess = new RobotReport();
                reportSuccess.Report = "سفارش کاربر " + c.ContactTitle + " با موفقیت ثبت شد ";
                reportSuccess.Success = true;
                reportSuccess.OrderId = o.OrderId;
                reportSuccess.Username = user.UserName;
                reportSuccess.Action = "NewOrder()";
                reportSuccess.ReportDate = DateTime.Now;
                crmRepository.AddReport(reportSuccess);

                crmRepository.Save();
                 
                return c.ContactId;
            }
            catch (Exception ex)
            {
                try
                {
                    ErrorLog error = new ErrorLog();
                    error.CreateDate = DateTime.Now;
                    error.ErrorPath = "WCF::CRMAPI.NewOrder()";
                    error.ExceptionDetails = ex.ToString();
                    error.ExceptionMessage = ex.Message;
                    error.Username = "crm_robot";
                    crmRepository.AddErrorLog(error);
                    crmRepository.Save();
                }
                catch { };
            }

            return -1;
        }

        private PersonalContact NewPersonalContact(OrderDTO o)
        {
            PersonalContact pc = new PersonalContact();
            pc.FatherName = o.Contact.FatherName;
            pc.FirstName = o.Contact.FirstName;
            pc.IdentityNumber = o.Contact.IdentityNumber;
            pc.LastName = o.Contact.LastName;
            pc.Birthday = o.Contact.Birthday;
            pc.IdentityIssuePlace = o.Contact.IdentityIssuePlace;
            pc.Job = o.Contact.Job;
            pc.EducationalMajor = o.Contact.EducationalMajor;
            pc.AcademicDegree = o.Contact.AcademicDegree;
            pc.NationalCode = o.Contact.NationalCode;
            return pc;
        }

        private CompanyContact NewCompanyContact(OrderDTO o)
        {
            CompanyContact cc = new CompanyContact();
            cc.CompanyName = o.Contact.CompanyName;
            cc.ManagerFirstName = o.Contact.ManagerFirstName;
            cc.ManagerLastName = o.Contact.ManagerLastName;
            cc.ManagerFullNameEnglish = o.Contact.ManagerFullNameEnglish;
            cc.ManagerNationalCode = o.Contact.ManagerNationalCode;
            cc.ManagerBirthday = o.Contact.ManagerBirthday;
            cc.ManagerEducationalMajor = o.Contact.ManagerEducationalMajor;
            cc.ManagerAcademicDegree = o.Contact.ManagerAcademicDegree;
            cc.CompanyActivityField = o.Contact.CompanyActivityField;
            cc.RegistrationNumber = o.Contact.RegistrationNumber;
            return cc;
        }

        public ServiceDTO[] GetServices()
        {
            CRMRepository repo = new CRMRepository();
            IList<Service> services = repo.GetServices().Where( s => s.Enable && s.Online ).ToList();

            var result = from s in services
                         select new ServiceDTO
                         {
                             Description = s.Description,
                             Price = s.Price,
                             ProvinceId = s.ProvinceId,
                             ServiceId = s.ServiceId,
                             ServiceName = s.ServiceName,
                             ServicePeriod = s.ServicePeriod,
                             TaxPercent = s.TaxPercent
                         };


            return result.ToArray();
        }

        public CityDTO[] GetCities()
        {
            CRMRepository repo = new CRMRepository();
            IList<City> cities = repo.GetCities();

            var result = from c in cities
                         select new CityDTO { CityId = c.CityId, CityName = c.CityName, ProvinceId = c.ProvinceId };

            return result.ToArray();
        }

        public ProvinceDTO[] GetProvinces()
        {
            CRMRepository repo = new CRMRepository();
            IList<Province> provinces = repo.GetProvinces().Where( p => p.Cities.Count > 0 ).ToList();

            List<ProvinceDTO> provinceDTOs = new List<ProvinceDTO>();

            foreach (var item in provinces)
            {
                ProvinceDTO p = new ProvinceDTO();
                p.Name = item.ProvinceName;

                foreach (var c in item.Cities)
                {
                    if (!String.IsNullOrEmpty(p.Cities))
                        p.Cities += " , ";

                    p.Cities += c.CityName;
                }

                provinceDTOs.Add(p);
            }

            return provinceDTOs.ToArray();
        }
    }
}
